package com.linktel.productionLine.EasyExcel.dailyAttendance;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.linktel.productionLine.EasyExcel.dailyAttendance.model.DailyAttendanceUnionKey;
import com.linktel.productionLine.EasyExcel.dailyAttendance.model.WriteDailyAttendance;
import com.linktel.productionLine.EasyExcel.util.Methods;
import com.linktel.productionLine.common.BaseContext;
import com.linktel.productionLine.common.ErrorCode;
import com.linktel.productionLine.dao.DailyAttendanceDao;
import com.linktel.productionLine.dao.ProductionLineDao;
import com.linktel.productionLine.entity.ProductionLine;
import com.linktel.productionLine.entity.dto.dailyAttendance.AttendanceInfoDTO;
import com.linktel.productionLine.entity.dto.productionLine.ProductionLineDTO;
import com.linktel.productionLine.exception.BusinessException;
import com.linktel.productionLine.service.DailyAttendanceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 上传excel文件，批量保存日出勤基础数据，创建easyExcel读的监听器
 *
 */
@Slf4j
public class DailyAttendanceListener extends AnalysisEventListener<WriteDailyAttendance> {

    private DailyAttendanceDao dailyAttendanceDao;
    private ProductionLineDao productionLineDao;
    private Long currentUserId;
    private final List<WriteDailyAttendance> list = new ArrayList<>();
    private List<String> productionLineCodeList = new ArrayList<>();
    private List<DailyAttendanceUnionKey> dailyAttendanceUnionKeys = new ArrayList<>();
    private DailyAttendanceService dailyAttendanceService;
    private Integer loadingNumber = 0;
    private Integer repeatedNumber = 0;
    private Integer unusefulNumber = 0;
    private Integer editNumber = 0;
    private Integer increasedNumber = 0;

    public DailyAttendanceListener(DailyAttendanceDao dailyAttendanceDao, Long currentUserId, ProductionLineDao productionLineDao, DailyAttendanceService dailyAttendanceService) {
        this.dailyAttendanceDao = dailyAttendanceDao;
        this.currentUserId = currentUserId;
        this.productionLineDao = productionLineDao;
        this.productionLineCodeList = productionLineDao.listProductionLine(currentUserId).stream().map(ProductionLineDTO::getCode).collect(Collectors.toList());
        this.dailyAttendanceService = dailyAttendanceService;
    }

    @Override
    public void invoke(WriteDailyAttendance data, AnalysisContext context) {
        loadingNumber++;
        String productionLineCode = data.getProductionLineCode();
        String attendanceDateStr = data.getAttendanceDate();
        DailyAttendanceUnionKey dailyAttendanceUnionKey = new DailyAttendanceUnionKey(productionLineCode, attendanceDateStr);
        if (StringUtils.isAnyBlank(productionLineCode, attendanceDateStr)) {
            log.info("{}, 传入的产线编码和出勤日期不能为空", data);
            unusefulNumber++;
            return ;
        }

        if (!productionLineCodeList.contains(productionLineCode)) {
            log.info("{}，该产线不存在在已有的产线中", data);
            unusefulNumber++;
            return ;
        }
        attendanceDateStr = Methods.getDateFromExcel(attendanceDateStr);

        log.info("region = {}", data);
        data.setAttendanceDate(attendanceDateStr);

//        LocalDate attendanceDate = LocalDate.parse(attendanceDateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//        dailyAttendanceService.saveNullEfficiencyData(productionLineCode, attendanceDate);
        if (dailyAttendanceUnionKeys.contains(dailyAttendanceUnionKey)) {
            repeatedNumber++;
            return ;
        }
        dailyAttendanceUnionKeys.add(dailyAttendanceUnionKey);
        list.add(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        BaseContext.setCurrentLog("");
        saveData();
    }

    private void saveData() {
        log.info("------------  开始存储数据  ----------");
        if (list.size() > 0) {
            List<AttendanceInfoDTO> attendanceInfoDTOList = dailyAttendanceDao.listAttendanceInfo(null, null, null);
            Map<DailyAttendanceUnionKey, Long> map = new HashMap<>();
            attendanceInfoDTOList.forEach(item -> {
                map.put(new DailyAttendanceUnionKey(item.getProductionLineCode(), item.getAttendanceDate().toString()), item.getId());
            });
            list.forEach(item -> {
                DailyAttendanceUnionKey dailyAttendanceUnionKey = new DailyAttendanceUnionKey(item.getProductionLineCode(), item.getAttendanceDate());
                if (map.containsKey(dailyAttendanceUnionKey)) {
                    editNumber++;
                    item.setId(map.get(dailyAttendanceUnionKey));
                } else {
                    increasedNumber++;
                }
            });
            dailyAttendanceDao.batchReplaceSave(list, currentUserId);
            BaseContext.setCurrentLog("加载到" + loadingNumber + "条数据，其中 "+ unusefulNumber +" 条不合法数据，" + repeatedNumber + "条重复数据；成功修改了" + editNumber + "条数据，新增了" + increasedNumber + "条数据。");
        } else {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "插入失败");
        }
    }

}
